import { create, all } from 'mathjs'
import {
  handleConcat,
  handleNumPrecision,
  getDaysBetween,
  handleNumSum,
  handleDomVisible
} from './custom'
// import { cloneDeep } from 'lodash-es'

/**
 * Math.js 是一个广泛应用于 JavaScript 和 Node.js 的数学库，这里主要使用它特有的表达式解析器
 * https://mathjs.org/index.html
 */
// 初始化mathjs
const math = create(all)

//自定义扩展函数
const customFunctions = {
  /** 字符串拼接 join(toArray(a,b,c))*/
  join: function (arr: [], separator = '/') {
    return handleConcat(arr, separator)
  },
  /** 小数位数度控制 */
  toFixed: (num: any, p = 2) => {
    return handleNumPrecision(num, p)
  },
  /** 处理最小值为0 */
  numberPositive: function (num: any) {
    return Math.max(0, num)
  },
  /**计算日期差 dataCalc(toArray(date1,date2))*/
  dateCalc: function (formula: any, type?: string) {
    if (!formula) return 0
    return getDaysBetween(formula, type)
  },
  /** 转数组 toArray(a,b,c) */
  toArray: function () {
    // eslint-disable-next-line prefer-rest-params
    return [...arguments]
  },
  multiSum: function () {
    return handleNumSum([...arguments])
  },
  // setDomVisible(['MAIN_BILL_DTO_reason_name','MAIN_BILL_DTO_expense_description'],1)
  setDomVisible: function () {
    const args = Array.from(arguments)
    if (args && args.length === 3) {
      const domIds = args[0] && args[0]._data
      const hideVal = args[1]
      const currentVal = args[2]
      handleDomVisible(domIds, hideVal, currentVal)
    }
  }
}
math.import(customFunctions)
/** 自定义函数 */
const customFunKeys = Object.keys(customFunctions)
/** 跨表计算函数 */
const customMultiFunKeys = ['multiSum']

/**
 * 执行函数表达式
 * @param formulas 函数表达式
 * @param execData 数据对象
 * @returns 表达式执行结果
 */
// function execFun(formulas: string, execData: any, caFieldArr?: Array<string>) {
//   const data = cloneDeep(execData)
//   if (caFieldArr && caFieldArr.length > 0) {
//     caFieldArr.forEach((key: string) => {
//       if (data[key] === undefined || data[key] === null || Number.isNaN(data[key])) {
//         data[key] = ''
//       }
//     })
//   }
//   let res: any = ''
//   try {
//     res = math.evaluate(formulas, data)
//     res = typeof res === 'number' ? numberFormate(res) : res
//   } catch (e) {
//     console.log(e, 'execFun wrong')
//     res = ''
//   }
//   return res
// }
/**
 * 解析函数或者js脚本
 * @param jsStr 函数或者js脚本
 * @param isFunc 是否是 math 内置函数
 * @returns
 */
function execJs(jsStr: string, isFunc: boolean) {
  let res = ''
  try {
    if (isFunc) {
      res = math.evaluate(jsStr)
    } else {
      res = eval(jsStr)
    }
  } catch (e) {
    console.log(e, 'exec wrong')
    res = ''
  }
  return res
}
/**
 *  * 对数字进行处理，解决精度错误问题
 * @param number 需要处理的数据
 * @param precision 精度
 * @returns
 */
function numberFormate(number: number | string, precision?: number) {
  if (typeof number === 'string' && !Number.isNaN(Number(number))) {
    number = Number(number)
  }
  const options: math.FormatOptions = {
    // precision: 10,
    precision: 16
  }
  if (precision) {
    options.precision = precision
    options.notation = 'fixed'
  }
  const result = math.format(number, options)
  if (!Number.isNaN(Number(result))) {
    return Number(result)
  } else {
    return result
  }
}

export { execFun, execJs, numberFormate, customFunKeys, customMultiFunKeys }

// 应用示例：
// const obj = {
//   a: '张三丰',
//   b: '武当真人',
//   c: '2023-10-10至2023-10-12',
//   // d: ['2023-12-11', '2023-12-18'],
//   d: ['2023-12-11', ''],
//   e: '2023-1-12',
//   num: 4.0,
//   f:'10',
//   g:'20',
//   m:'30'
// };
// let multiObj = {
//   BILL_LIST:{
//     apply_money:10
//   },
//   DETAIL_LIST:{
//     apply_money:20
//   }
// }
// console.log(math.evaluate('dateCalc(d)', obj));
// console.log('join=', math.evaluate('join(toArray(a,b))', obj));
// console.log('+=', execFun('f+g+m+n', obj),['f','g','m','n']);
// console.log('multiSum', execFun('multiSum(BILL_LIST[apply_money],DETAIL_LIST[apply_money])', multiObj));
// console.log('multiSum', execFun('multiSum(BILL_LIST.apply_money,DETAIL_LIST.apply_money)', multiObj));
// console.log('evaluate', math.evaluate('BILL_LIST.apply_money+DETAIL_LIST.apply_money', multiObj),['']);
